<?php

namespace App\Http\Middleware;

use App\Common\Utils\JsonResponse;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use HTMLPurifier;
use HTMLPurifier_Config;

class FilterParameters extends Request
{
    protected $_errMsg = '';

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        //$requestData = $request->all();
        $rules = [
            // 添加更多规则...
        ];
        /**
        $validator = Validator::make($request->all(), $rules);
        if ($validator->fails()) {
            return JsonResponse::error($validator->errors());
        }

        // 在这里进一步处理或修改请求参数
        $request->merge($this->cleanInput($request->all()));**/
        // 过滤 XSS 攻击
        /**
        $config = HTMLPurifier_Config::createDefault();
        $purifier = new HTMLPurifier($config);
        foreach ($request->all() as $key => $value) {
            $request->merge([$key => $purifier->purify($value)]);
        }**/
        //var_dump($this->getContent());exit();
        /**
        if(is_array($requestData)) {
            foreach ($requestData as $k => &$v) {
                if(!is_array($v)) {
                    $v = $this->remove_xss($v);
                    $v = $this->filterSqlKeywords($v);
                }
            }
            $request->replace($requestData);
        }else{
            $requestData = $this->remove_xss($requestData);
            $requestData = $this->filterSqlKeywords($requestData);
            $request->replace($requestData);
        }**/
        $requestData = $this->getContent();
        $requestData = $this->remove_xss($requestData);
        $requestData = $this->filterSqlKeywords($requestData);
        if($requestData) {
            $dataResponse = json_decode($requestData, TRUE);
            if(is_array($dataResponse)) {
                $request->replace(json_decode($requestData, TRUE));
            }
        }
        //dd($requestData);
        // 防止 SQL 注入 (Laravel 自动处理这部分，通常在模型中使用)
        // 但你可以在这里进一步强化验证逻辑
        return $next($request);
    }



    protected function cleanInput(array $input)
    {
        $cleanInput = [];
        foreach ($input as $key => $value) {
            $cleanInput[$key] = e($value); // 使用e()函数转义HTML实体，防止XSS攻击
        }
        return $cleanInput;
    }

    public function isValid(){
        $requestData = $this->getData();
        $rules = $this->rules();
        $messages = $this->messages();

        $validator = Validator::make($requestData, $rules, $messages);
        if ($validator->fails()) {
            $errors = $validator->errors()->all();
            $this->_errMsg = $errors[0];
            return FALSE;
        }else{
            return TRUE;
        }
    }

    public function getData($xssfilter=TRUE,$sqlfilter=TRUE){
        $requestData = $this->getContent();
        if($xssfilter){
            $requestData = $this->remove_xss($requestData);
        }
        if($sqlfilter){
            $requestData = $this->filterSqlKeywords($requestData);
        }
        return json_decode($requestData, TRUE );
    }

    public function getErrMsg(){
        return $this->_errMsg;
    }

    function remove_xss($val) {
        $val = preg_replace ( '/([\x00-\x08\x0b-\x0c\x0e-\x19])/', '', $val );

        $search = 'abcdefghijklmnopqrstuvwxyz';
        $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $search .= '1234567890!@#$%^&*()';
        $search .= '~`";:?+/={}[]-_|\'\\';
        for($i = 0; $i < strlen ( $search ); $i ++) {

            $val = preg_replace ( '/(&#[xX]0{0,8}' . dechex ( ord ( $search [$i] ) ) . ';?)/i', $search [$i], $val );

            $val = preg_replace ( '/(�{0,8}' . ord ( $search [$i] ) . ';?)/', $search [$i], $val );
        }

        $ra1 = array (
            'javascript',
            'vbscript',
            'expression',
            'applet',
            'meta',
            'xml',
            'blink',
            'script',
            'object',
            'iframe',
            'frame',
            'frameset',
            'ilayer',
            'bgsound'
        );
        $ra2 = array (
            'onabort',
            'onactivate',
            'onafterprint',
            'onafterupdate',
            'onbeforeactivate',
            'onbeforecopy',
            'onbeforecut',
            'onbeforedeactivate',
            'onbeforeeditfocus',
            'onbeforepaste',
            'onbeforeprint',
            'onbeforeunload',
            'onbeforeupdate',
            'onblur',
            'onbounce',
            'oncellchange',
            'onchange',
            'onclick',
            'oncontextmenu',
            'oncontrolselect',
            'oncopy',
            'oncut',
            'ondataavailable',
            'ondatasetchanged',
            'ondatasetcomplete',
            'ondblclick',
            'ondeactivate',
            'ondrag',
            'ondragend',
            'ondragenter',
            'ondragleave',
            'ondragover',
            'ondragstart',
            'ondrop',
            'onerror',
            'onerrorupdate',
            'onfilterchange',
            'onfinish',
            'onfocus',
            'onfocusin',
            'onfocusout',
            'onhelp',
            'onkeydown',
            'onkeypress',
            'onkeyup',
            'onlayoutcomplete',
            'onload',
            'onlosecapture',
            'onmousedown',
            'onmouseenter',
            'onmouseleave',
            'onmousemove',
            'onmouseout',
            'onmouseover',
            'onmouseup',
            'onmousewheel',
            'onmove',
            'onmoveend',
            'onmovestart',
            'onpaste',
            'onpropertychange',
            'onreadystatechange',
            'onreset',
            'onresize',
            'onresizeend',
            'onresizestart',
            'onrowenter',
            'onrowexit',
            'onrowsdelete',
            'onrowsinserted',
            'onscroll',
            'onselect',
            'onselectionchange',
            'onselectstart',
            'onstart',
            'onstop',
            'onsubmit',
            'onunload'
        );
        $ra = array_merge ( $ra1, $ra2 );

        $found = true;
        while ( $found == true ) {
            $val_before = $val;
            for($i = 0; $i < sizeof ( $ra ); $i ++) {
                $pattern = '/';
                for($j = 0; $j < strlen ( $ra [$i] ); $j ++) {
                    if ($j > 0) {
                        $pattern .= '(';
                        $pattern .= '(&#[xX]0{0,8}([9ab]);)';
                        $pattern .= '|';
                        $pattern .= '|(�{0,8}([9|10|13]);)';
                        $pattern .= ')*';
                    }
                    $pattern .= $ra [$i] [$j];
                }
                $pattern .= '/i';
                $replacement = substr ( $ra [$i], 0, 2 ) . ' ' . substr ( $ra [$i], 2 );
                $val = preg_replace ( $pattern, $replacement, $val );
                if ($val_before == $val) {

                    $found = false;
                }
            }
        }
        return $val;
    }

    function filterSqlKeywords($input) {
        // 定义SQL关键字数组
        $keywords = ['select', 'insert', 'update', 'delete', 'drop', 'create', 'alter', 'cast', 'execute', 'sleep', 'union','where'];

        // 使用正则表达式替换掉关键字
        $pattern = sprintf('/\\b(?:%s)\\b/i', implode('|', $keywords));
        return preg_replace($pattern, '', $input);
    }
}
